<?php
/**
 * 渲染组件函数
 * 安全加载组件并传递参数，避免变量冲突
 * 
 * @param string|array $component 组件名称或组件信息数组
 * @param string|null $configKey 配置键，用于获取组件配置
 * @param array $data 传递给组件的数据数组
 * @param array $options 选项数组
 * @return bool 是否渲染成功
 */
function renderComponent($component, $configKey = null, $data = [], $options = []) {
    // 默认选项
    $defaultOptions = [
        'useCache' => false,    // 是否使用组件缓存
        'cacheTime' => 3600,   // 缓存时间（秒）
        'debug' => false,      // 是否启用调试模式
    ];
    
    $options = array_merge($defaultOptions, $options);
    
    // 获取全局配置和映射表（通过闭包或服务容器获取，避免global关键字）
    $getGlobalData = function() {
        global $fragmentMap, $pageConfig;
        return [
            'fragmentMap' => $fragmentMap,
            'pageConfig' => $pageConfig
        ];
    };
    
    $globals = $getGlobalData();
    $fragmentMap = $globals['fragmentMap'];
    $pageConfig = $globals['pageConfig'];
    
    // 确定组件名称和配置键
    if (is_array($component)) {
        $configKey = $component['id'] ?? $configKey;
        $componentName = $component['name'];
        // 从组件数组中提取额外数据
        if (isset($component['data']) && is_array($component['data'])) {
            $data = array_merge($data, $component['data']);
        }
    } else {
        $componentName = $component;
    }
    
    // 确定要使用的配置键
    $configKey = $configKey ?: $componentName;
    
    // 构建缓存键（如果启用缓存）
    $cacheKey = null;
    if ($options['useCache'] && function_exists('getComponentCache')) {
        $cacheKey = 'component_' . md5($componentName . '_' . $configKey . '_' . serialize($data));
        $cachedOutput = getComponentCache($cacheKey, $options['cacheTime']);
        if ($cachedOutput !== false) {
            echo $cachedOutput;
            return true;
        }
    }
    
    // 查找组件文件
    $componentFile = null;
    if (isset($fragmentMap[$componentName])) {
        $componentFile = FRAGMENTS_PATH . $fragmentMap[$componentName];
    } elseif (file_exists(FRAGMENTS_PATH . $componentName . '.php')) {
        $componentFile = FRAGMENTS_PATH . $componentName . '.php';
    }
    
    // 检查组件文件是否存在
    if (!file_exists($componentFile)) {
        $errorMsg = "Component file not found: {$componentFile} (component: {$componentName})";
        error_log($errorMsg);
        if ($options['debug']) {
            echo "<!-- {$errorMsg} -->";
        }
        return false;
    }
    
    // 准备组件数据
    $componentData = [
        'configKey' => $configKey,
        'pageConfig' => $pageConfig,
        'componentConfig' => isset($pageConfig['components'][$configKey]) ? $pageConfig['components'][$configKey] : []
    ];
    
    // 合并用户数据
    if (!empty($data)) {
        $componentData = array_merge($componentData, $data);
        // 深度合并配置
        if (isset($data['componentConfig']) && is_array($data['componentConfig'])) {
            $componentData['componentConfig'] = merge_config_recursive(
                $componentData['componentConfig'],
                $data['componentConfig']
            );
        }
    }
    
    // 使用输出缓冲捕获组件输出
    ob_start();
    
    try {
        // 使用闭包创建隔离的作用域
        $renderClosure = function() use ($componentFile, $componentData) {
            // 提取组件数据到局部变量
            extract($componentData);
            
            // 包含组件文件
            include $componentFile;
        };
        
        // 执行闭包
        $renderClosure();
        
        // 获取组件输出
        $output = ob_get_clean();
        
        // 存储缓存（如果启用缓存）
        if ($options['useCache'] && function_exists('setComponentCache') && $cacheKey) {
            setComponentCache($cacheKey, $output);
        }
        
        // 输出组件内容
        echo $output;
        return true;
    } catch (Exception $e) {
        ob_end_clean();
        $errorMsg = "Error rendering component {$componentName}: {$e->getMessage()}";
        error_log($errorMsg);
        if ($options['debug']) {
            echo "<!-- {$errorMsg} -->";
        }
        return false;
    }
}

/**
 * 递归合并两个配置数组
 * 
 * @param array $array1 第一个数组
 * @param array $array2 第二个数组
 * @return array 合并后的数组
 */
function merge_config_recursive($array1, $array2) {
    foreach ($array2 as $key => $value) {
        if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])) {
            $array1[$key] = merge_config_recursive($array1[$key], $value);
        } else {
            $array1[$key] = $value;
        }
    }
    return $array1;
}

/**
 * 获取组件缓存
 * 注意：这是一个示例实现，需要根据实际的缓存系统进行调整
 * 
 * @param string $key 缓存键
 * @param int $expire 过期时间
 * @return mixed 缓存内容或false
 */
function getComponentCache($key, $expire) {
    // 示例：检查文件系统缓存
    $cacheDir = BASE_PATH . '/cache/components/';
    $cacheFile = $cacheDir . $key . '.cache';
    
    if (!is_dir($cacheDir)) {
        mkdir($cacheDir, 0755, true);
    }
    
    if (file_exists($cacheFile) && (filemtime($cacheFile) + $expire > time())) {
        return file_get_contents($cacheFile);
    }
    
    return false;
}

/**
 * 设置组件缓存
 * 注意：这是一个示例实现，需要根据实际的缓存系统进行调整
 * 
 * @param string $key 缓存键
 * @param string $content 缓存内容
 * @return bool 是否设置成功
 */
function setComponentCache($key, $content) {
    // 示例：设置文件系统缓存
    $cacheDir = BASE_PATH . '/cache/components/';
    $cacheFile = $cacheDir . $key . '.cache';
    
    if (!is_dir($cacheDir)) {
        mkdir($cacheDir, 0755, true);
    }
    
    return file_put_contents($cacheFile, $content) !== false;
}